﻿// Gateway.Api 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
// 
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
// 
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Aurora.AI.Common.Extensions;
using Aurora.AI.Common.Helper;
using Aurora.AI.SqlSugar.Framework.Repositories;
using Aurora.AI.Wiki.Domain.Domain.ChatApplications.Repositories;
using Aurora.AI.Wiki.Models;
using Aurora.AI.Wiki.Services.ChatApplication.Dialog;
using Aurora.AI.Wiki.Services.ChatApplication.Record;
using Mapster;
using Newtonsoft.Json;
using SqlSugar;

namespace Aurora.AI.Wiki.Services.ChatApplication;

public class ChatApplicationService
{
    private readonly IChatApplicationRepository _chatApplicationRepository;
    private readonly IRepository<Domain.Domain.ChatApplications.Aggregates.ChatApplication> _repository;

    public ChatApplicationService(IChatApplicationRepository chatApplicationRepository,
        IRepository<Domain.Domain.ChatApplications.Aggregates.ChatApplication> repository)
    {
        _chatApplicationRepository = chatApplicationRepository;
        _repository = repository;
    }

    // 添加
    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public async Task<bool> Add(ChatApplicationAddRequest request)
    {
        await _chatApplicationRepository.CreateApplication(
            new Domain.Domain.ChatApplications.Aggregates.ChatApplication(request.Name, request.OperatorId));
        return true;
    }

    // 编辑
    public async Task<bool> Update(ChatApplicationUpdateRequest request)
    {
        var byIdAsync = await _repository.GetByIdAsync(request.Id);
        if (byIdAsync == null)
        {
            throw new ArgumentException("未找到应用");
        }

        byIdAsync.Name = request.Name;
        byIdAsync.Relevancy = request.Relevancy;
        byIdAsync.ReferenceUpperLimit = request.ReferenceUpperLimit;
        byIdAsync.ChatModel = request.ChatModel;
        byIdAsync.Prompt = request.Prompt;
        byIdAsync.Temperature = request.Temperature;
        byIdAsync.MaxResponseToken = request.MaxResponseToken;
        byIdAsync.Template = request.Template;
        byIdAsync.Parameter = (request.Parameter?.Count > 0) ? JsonConvert.SerializeObject(request.Parameter) : "";
        byIdAsync.Opener = request.Opener;
        byIdAsync.NoReplyFoundTemplate = request.NoReplyFoundTemplate;
        byIdAsync.ShowSourceFile = request.ShowSourceFile;
        byIdAsync.WikiIds = request.WikiIds?.Count > 0 ? string.Join(",", request.WikiIds) : "";
        byIdAsync.Extend = (request.Extend?.Count > 0) ? JsonConvert.SerializeObject(request.Extend) : "";
        byIdAsync.FunctionIds = request.FunctionIds?.Count > 0 ? string.Join(",", request.FunctionIds) : "";
        byIdAsync.Modifier = request.OperatorId;
        byIdAsync.ModificationTime = DateTime.Now;
        byIdAsync.ChatType = request.ChatType;
        byIdAsync.ImageAnalysisModel = request.ImageAnalysisModel;
        byIdAsync.ImageAnalysisPrompt = request.ImageAnalysisPrompt;
        byIdAsync.EnableWebSearch = request.EnableWebSearch;
        await _repository.UpdateAsync(byIdAsync);
        return true;
    }

    // 删除
    public async Task<bool> Delete(string id)
    {
        await _repository.DeleteAsync(id);
        return true;
    }

    // 列表
    public async Task<(List<ChatApplicationPageListResponse> list, int total)> List(int page, int size)
    {
        var pageListAsync = await _repository.GetPageListAsync(x => x.IsDeleted == false, page, size,
            x => x.CreationTime, OrderByType.Desc);
        List<ChatApplicationPageListResponse> list = pageListAsync.list.Adapt<List<ChatApplicationPageListResponse>>();
        return (list, pageListAsync.total);
    }

    // 详情
    public async Task<ChatApplicationDetailResponse> Detail(string id)
    {
        var data = await _chatApplicationRepository.GetByIdAsync(id);
        if (data == null) return null;
        ChatApplicationDetailResponse chatApplicationDetailResponse = new ChatApplicationDetailResponse
        {
            Id = data.Id,
            Name = data.Name,
            ChatModel = data.ChatModel,
            Prompt = data.Prompt,
            Template = data.Template,
            Temperature = data.Temperature ?? 70,
            MaxResponseToken = data.MaxResponseToken ?? 1024,
            Opener = data.Opener,
            ChatType = data.ChatType,
            NoReplyFoundTemplate = data.NoReplyFoundTemplate,
            ShowSourceFile = data.ShowSourceFile ?? false,
            ImageAnalysisModel = data.ImageAnalysisModel,
            ImageAnalysisPrompt = data.ImageAnalysisPrompt,
            EnableWebSearch = data.EnableWebSearch,
            WikiIds = string.IsNullOrEmpty(data.WikiIds) ? new List<string>() : data.WikiIds.Split(",").ToList(),
            Relevancy = data.Relevancy ?? 0
        };
        //todo 
        return chatApplicationDetailResponse;
    }


    /// <summary>
    /// 保存聊天记录
    /// </summary>
    /// <param name="applicationId">应用id</param>
    /// <param name="question">提问内容</param>
    /// <param name="dialogId"></param>
    /// <returns></returns>
    public async Task<bool> CreateChatRecord(string applicationId, string question, string dialogId, string imageUrl)
    {
        if (string.IsNullOrEmpty(question)) return false;
        Domain.Domain.ChatApplications.Aggregates.ChatRecord chatRecord =
            new(Guid.NewGuid().ToString().Replace("-", ""), applicationId, question)
            {
                DialogId = dialogId,
                Role = "user",
                AIType = "chat",
                Images = string.IsNullOrEmpty(imageUrl)
                    ? ""
                    : AuroraAIJsonSerializer.Serialize(new List<string>() { imageUrl }),
            };
        await _chatApplicationRepository.CreateChatRecord(chatRecord);
        return true;
    }

    public async Task<string> CreateChatDialog(ChatApplicationDialogAddRequest request)
    {
        Domain.Domain.ChatApplications.Aggregates.ChatApplicationDialog chatDialog =
            new(request.ApplicationId, request.Name, request.OperatorId, request.AiType);
        return await _chatApplicationRepository.CreateChatDialogAsync(chatDialog);
    }

    public async Task<bool> UpdateChatDialog(ChatApplicationDialogUpdateRequest request)
    {
        Domain.Domain.ChatApplications.Aggregates.ChatApplicationDialog chatDialogByIdAsync =
            await _chatApplicationRepository.GetChatDialogByIdAsync(request.Id);
        if (chatDialogByIdAsync == null)
            return false;
        chatDialogByIdAsync.ChatCount = request.ChatCount;
        chatDialogByIdAsync.Name = request.Name;
        chatDialogByIdAsync.Modifier = request.OperatorId;
        chatDialogByIdAsync.ModificationTime = DateTime.Now;
        return await _chatApplicationRepository.UpdateChatDialogAsync(chatDialogByIdAsync);
    }


    public async Task<bool> RemoveChatDialogAsync(string id)
    {
        await _chatApplicationRepository.RemoveChatDialogAsync(id);
        return true;
    }

    public async Task<List<ChatApplicationDialogListResponse>> GetChatDialogListAsync(string applicationId,
        string aiType)
    {
        List<ChatApplicationDialogListResponse> result = new();
        List<Domain.Domain.ChatApplications.Aggregates.ChatApplicationDialog> chatDialogList =
            await _chatApplicationRepository.GetChatDialogListAsync(applicationId, aiType);
        if (chatDialogList.Count <= 0)
            return new List<ChatApplicationDialogListResponse>();
        foreach (Domain.Domain.ChatApplications.Aggregates.ChatApplicationDialog item in chatDialogList)
        {
            result.Add(new ChatApplicationDialogListResponse()
            {
                ApplicationId = item.ApplicationId,
                ChatCount = item.ChatCount,
                Id = item.Id,
                ModificationTime = item.ModificationTime!.Value,
                Name = item.Name
            });
        }

        return result;
    }

    /// <summary>
    /// 获取聊天记录
    /// </summary>
    /// <param name="dialogId"></param>
    /// <returns></returns>
    public async Task<List<ChatRecordListResponse>> GetRecordListByDialogId(string dialogId)
    {
        var data = await _chatApplicationRepository.GetChatRecordListAsync(dialogId);
        if (data.Count <= 0)
            return new List<ChatRecordListResponse>();
        List<ChatRecordListResponse> result = new();
        foreach (Domain.Domain.ChatApplications.Aggregates.ChatRecord item in data)
        {
            result.Add(new ChatRecordListResponse()
            {
                ApplicationId = item.ApplicationId,
                DialogId = item.DialogId,
                Id = item.Id,
                Role = item.Role,
                Question = item.Question,
                CreationTime = item.CreationTime!.Value,
                AIType = item.AIType,
                Images = string.IsNullOrEmpty(item.Images)
                    ? new()
                    : AuroraAIJsonSerializer.Deserialize<List<string>>(item.Images),
                WebSearch = string.IsNullOrEmpty(item.WebSearch)
                    ? new List<WebSearchParameter>()
                    : AuroraAIJsonSerializer.Deserialize<List<WebSearchParameter>>(item.WebSearch),
                SourceFiles = string.IsNullOrEmpty(item.SourceFiles)
                    ? new List<string>()
                    : item.SourceFiles.Split(",").ToList(),
                Videos = string.IsNullOrEmpty(item.Videos)
                    ? new List<VideoParameter>()
                    : AuroraAIJsonSerializer.Deserialize<List<VideoParameter>>(item.Videos)
            });
        }

        return result;
    }

    /// <summary>
    /// 添加聊天记录
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public async Task<bool> AddRecord(ChatRecordCreateRequest request)
    {
        Domain.Domain.ChatApplications.Aggregates.ChatRecord chatRecord =
            new(IdHelper.GenerateId(), request.ApplicationId,
                request.Question)
            {
                DialogId = request.DialogId,
                Role = request.Role,
                AIType = request.AIType ?? "chat",
                Images = request.Images?.Count > 0 ? AuroraAIJsonSerializer.Serialize(request.Images) : "",
                WebSearch = request.WebSearch?.Count > 0 ? AuroraAIJsonSerializer.Serialize(request.WebSearch) : "",
                SourceFiles = request.SourceFiles?.Count > 0 ? string.Join(",", request.SourceFiles) : "",
                Videos = request.Videos?.Count > 0 ? AuroraAIJsonSerializer.Serialize(request.Videos) : "",
            };
        await _chatApplicationRepository.CreateChatRecord(chatRecord);
        return true;
    }
}